package com.zillion.employee.service.impl;

import com.zillion.common.core.redis.RedisCache;
import com.zillion.employee.domain.EmployeeReserve;
import com.zillion.employee.domain.PersonApply;
import com.zillion.employee.domain.PersonReserve;
import com.zillion.employee.domain.UnitReserve;
import com.zillion.employee.domain.vo.MineProgressVO;
import com.zillion.employee.mapper.EmployeeReserveMapper;
import com.zillion.employee.mapper.PersonApplyMapper;
import com.zillion.employee.service.IEmployeeReserveService;
import com.zillion.health.domain.vo.UISelectDataVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
public class EmployeeReserveServiceImpl implements IEmployeeReserveService {

    @Autowired
    private EmployeeReserveMapper employeeReserveMapper;

    @Autowired
    private PersonApplyMapper personApplyMapper;

    @Autowired
    private RedisCache redisCache; // 注入 RedisCache

    /*医院列表*/
    private static final String HOSPITALS_KEY = "hospitals:list";
    private static final String HOSPITAL_ADDRESS_KEY = "hospitalAddress:list";

    /**
     * 根据身份证查询预约信息
     *
     * @param idCard 身份证号
     * @return 申报信息
     */
    @Override
    public PersonApply selectApplyInfoByIdCard(String idCard) {
        return employeeReserveMapper.selectApplyInfoByIdCard(idCard);
    }

    /**
     * 根据园区id查询医院信息
     *
     * @param parkId 园区id
     * @return 医院信息
     */
    @Override
    public List<UISelectDataVo> selectHospitalInfoByParkId(Integer parkId) {
        return employeeReserveMapper.selectHospitalInfoByParkId(parkId);
    }

    /**
     * 添加预约信息
     *
     * @param employeeReserve 预约信息
     * @return 添加结果
     */
    @Override
    public int addPeronReserve(EmployeeReserve employeeReserve) {
        // 根据身份证号查询是否在一年内预约过
        PersonApply personApply = employeeReserveMapper.selectApplyInfoByIdCard(employeeReserve.getIdCard());
        Integer tjStatus = personApply.getTjStatus(); // 如果状态为 3 则说明预约过期,可以再次预约
        String reserveDate = personApply.getReserveDate();
        boolean isInOneYear = isExactlyOneYearDifference(reserveDate);

        // 一年内没有预约过才让预约
        int row = 0;
        if (isInOneYear || 3 == tjStatus) {
            row = employeeReserveMapper.addPeronReserve(employeeReserve);
            // 添加成功过后更改申报信息表中的预约状态
            if (row > 0) {
                String idCard = employeeReserve.getIdCard();
                personApplyMapper.updateReserveStatusByIdCard(idCard);
            }
        }
        return row;
    }

    /**
     * 添加单位预约信息
     *
     * @param unitReserve 单位预约信息
     * @return 添加结果
     */
    @Override
    public int addUnitPersonReserve(UnitReserve unitReserve) {
        // 获取单位预约信息
        List<PersonReserve> reservePersons = unitReserve.getReservePersons();
        // 将员工信息转换成单位预约信息
        List<EmployeeReserve> unitReservePersons = new ArrayList<>();
        for (PersonReserve reservePerson : reservePersons) {
            EmployeeReserve employeeReserve = getEmployeeReserve(unitReserve, reservePerson);
            unitReservePersons.add(employeeReserve);
        }
        // 批量添加单位预约信息
        int row = employeeReserveMapper.addUnitPersonReserve(unitReservePersons);
        // 添加成功过后更改申报信息表中的预约状态
        if (row > 0) {
            List<String> idCards = new ArrayList<>();
            for (PersonReserve reservePerson : reservePersons) {
                idCards.add(reservePerson.getIdCard());
            }
            personApplyMapper.updateReserveStatusByIdCards(idCards); // 传 List<String
        }
        return row;
    }

    /**
     * 获取所有医院信息
     *
     * @return 医院信息
     */
    @Override
    public List<UISelectDataVo> loadAllHospitals() {
        // 从 Redis 获取数据
        List<UISelectDataVo> allHospitalList = redisCache.getCacheList(HOSPITALS_KEY);
        if (allHospitalList == null || allHospitalList.isEmpty()) {
            // 如果 Redis 中没有数据，则从数据库获取
            allHospitalList = employeeReserveMapper.loadAllHospitals();
            if (allHospitalList != null && !allHospitalList.isEmpty()) {
                // 将数据写入 Redis
                redisCache.setCacheList(HOSPITALS_KEY, allHospitalList);
            }
        }
        return allHospitalList;
    }

    @Override
    public List<UISelectDataVo> loadAllHospitalAddress() {
        // 从 Redis 获取数据
        List<UISelectDataVo> allHospitalAddressList = redisCache.getCacheList(HOSPITAL_ADDRESS_KEY);
        if (allHospitalAddressList == null || allHospitalAddressList.isEmpty()) {
            // 如果 Redis 中没有数据，则从数据库获取
            allHospitalAddressList = employeeReserveMapper.loadAllHospitalAddress();
            if (allHospitalAddressList != null && !allHospitalAddressList.isEmpty()) {
                // 将数据写入 Redis
                redisCache.setCacheList(HOSPITALS_KEY, allHospitalAddressList);
            }
        }
        return allHospitalAddressList;
    }

    @Override
    public MineProgressVO loadUserProgress(String idCard) {
        return employeeReserveMapper.loadUserProgress(idCard);
    }

    /**
     * 获取单位预约信息
     *
     * @param unitReserve   单位预约信息
     * @param reservePerson 员工信息
     * @return 单位预约信息
     */
    private static EmployeeReserve getEmployeeReserve(UnitReserve unitReserve, PersonReserve reservePerson) {
        EmployeeReserve employeeReserve = new EmployeeReserve();
        employeeReserve.setName(reservePerson.getName());
        employeeReserve.setIdCard(reservePerson.getIdCard());
        employeeReserve.setPhone(reservePerson.getPhone());
        employeeReserve.setReserveHospital(unitReserve.getReserveHospital());
        employeeReserve.setReserveDate(unitReserve.getReserveDate());
        employeeReserve.setReserveHour(unitReserve.getReserveHour());
        employeeReserve.setIsUnit(1);
        employeeReserve.setUnitName(unitReserve.getUnitName());
        employeeReserve.setSocialCreditCode(unitReserve.getSocialCreditCode());
        return employeeReserve;
    }

    /**
     * 根据社会信用代码获取单位预约信息
     *
     * @param socialCreditCode 社会信用代码
     * @return 单位预约信息
     */
    @Override
    public UnitReserve getUnitReserveInfo(String socialCreditCode) {
        // 获取单位预约信息
        UnitReserve unitReserveInfo = employeeReserveMapper.getUnitReserveInfo(socialCreditCode);
        if (unitReserveInfo != null) {
            // 获取单位中员工的信息
            List<PersonReserve> reservePersons = employeeReserveMapper.getReservePersons(socialCreditCode);
            unitReserveInfo.setReservePersons(reservePersons);
        }
        return unitReserveInfo;
    }

    // 更精确地比较是否相差一年
    public boolean isExactlyOneYearDifference(String reserveDate) {
        if (reserveDate == null || reserveDate.isEmpty()) {
            return true;
        }

        // 解析预约日期
        LocalDate reserveLocalDate = LocalDate.parse(reserveDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 计算一年后的预约日期
        LocalDate oneYearLater = reserveLocalDate.plusYears(1);

        // 判断当前日期是否等于或超过预约日期的一年后
        return currentDate.isEqual(oneYearLater) || currentDate.isAfter(oneYearLater);
    }
}
